package org.winplus.serial;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;

import org.winplus.serial.utils.SerialPort;
import org.winplus.serial.utils.SerialPortFinder;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

public abstract class SerialPortActivity extends Activity {
    private static final String TAG = "SerialPortActivity";
	protected Application mApplication;
	protected SerialPort mSerialPort;
	protected OutputStream mOutputStream;
	protected InputStream mInputStream;
	protected ReadThread mReadThread;

//    private EditText mEtReception;
    private TextView mTvReception;
    private Spinner spinnerBaudrate,spinnerPath;

	protected class ReadThread extends Thread {
		@Override
		public void run() {
			Log.d(TAG,"read thread start.");
			super.run();
			while (!isInterrupted()) {
				int size;
				try {
					byte[] buffer = new byte[64];
					if (mInputStream == null) {
                        Log.d(TAG,"mInputStream is null. return");
                        return;
                    }

					size = mInputStream.read(buffer);
					if (size > 0) {
						onDataReceived(buffer, size);
					}
				} catch (IOException e) {
					e.printStackTrace();
					return;
				}
			}
		}
	}

    private void openSerialPort() {

        try {
            mSerialPort = mApplication.getSerialPort();
            mOutputStream = mSerialPort.getOutputStream();
            mInputStream = mSerialPort.getInputStream();

                /* Create a receiving thread */
            mReadThread = new ReadThread();
            mReadThread.start();
        } catch (SecurityException e) {
            DisplayError(R.string.error_security);
        } catch (IOException e) {
            DisplayError(R.string.error_unknown);
        } catch (InvalidParameterException e) {
            DisplayError(R.string.error_configuration);
        }
    }

	protected void DisplayError(int resourceId) {
		AlertDialog.Builder b = new AlertDialog.Builder(this);
		b.setTitle("Error");
		b.setMessage(resourceId);
		b.setPositiveButton("OK", new OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				SerialPortActivity.this.finish();
			}
		});
		b.show();
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mApplication = (Application) getApplication();
        setContentView(R.layout.main);
        initView();
	}

    private void initView() {
        //baud rate spinner
        spinnerBaudrate = (Spinner)findViewById(R.id.spinner_baud_rate);
        String[] baudRates = getResources().getStringArray(R.array.baudrates_name);
        ArrayAdapter<String> baudRateAdapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_dropdown_item,baudRates);
        spinnerBaudrate.setAdapter(baudRateAdapter);

        //serial port spinner
        spinnerPath = (Spinner)findViewById(R.id.spinner_serial_port);
        SerialPortFinder serialPortFinder = new SerialPortFinder();
        String[] paths = serialPortFinder.getAllDevicesPath();
        ArrayAdapter<String> pathsAdapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_dropdown_item,paths);
        spinnerPath.setAdapter(pathsAdapter);

        SharedPreferences preferences = getSharedPreferences("serialport",MODE_PRIVATE);
        String path = preferences.getString("path","");
        int baudRate = preferences.getInt("baudrate",50);

        //init spinner


        mTvReception = (TextView)findViewById(R.id.EditTextReception);
        //send
        EditText Emission = (EditText) findViewById(R.id.EditTextEmission);
        Emission.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                Log.d(TAG, "onEditorAction");
                int i;
                CharSequence t = v.getText();
                char[] text = new char[t.length()];
                for (i = 0; i < t.length(); i++) {
                    text[i] = t.charAt(i);
                }
                try {
                    mOutputStream.write(new String(text).getBytes());
                    mOutputStream.write('\n');
                    Log.d(TAG, "send: " + v.getText());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return false;
            }
        });
    }

    public void onOpenSerial(View view) {

    }

    private void getSerialport() {
        SerialPortFinder serialPortFinder = new SerialPortFinder();
        serialPortFinder.getAllDevices();
        serialPortFinder.getAllDevicesPath();

    }

    protected void onDataReceived(final byte[] buffer, final int size) {
        runOnUiThread(new Runnable() {
            public void run() {
                Log.d(TAG,"data received.");
                if (mTvReception != null) {
                    mTvReception.append(new String(buffer, 0, size));
                }
            }
        });
    }

	@Override
	protected void onDestroy() {
		if (mReadThread != null)
			mReadThread.interrupt();
		mApplication.closeSerialPort();
		mSerialPort = null;
		super.onDestroy();
	}
}
